
trait Product {
    fn consume(&self);
}

struct Product1 {
    material1: String,
}

struct Product2 {
    material1: String,
    material2: String,
}

impl Product for Product1 {
    fn consume(&self) {
        println!("Product1:material1:{}.", self.material1);
    }
}

impl Product for Product2 {
    fn consume(&self) {
        println!(
            "Product2:material1:{},material2:{}.",
            self.material1, self.material2
        );
    }
}

enum ProductType {
    Product1(String),
    Product2(String, String),
}

fn new_product(product_type: ProductType) -> Box<dyn Product> {
    match product_type {
        ProductType::Product1(material1) => Box::new(Product1 { material1 }),
        ProductType::Product2(material1, material2) => Box::new(Product2 {
            material1,
            material2,
        }),
    }
}

#[test]
fn test_factory() {
    let array: [ProductType; 2] = [
        ProductType::Product1(String::from("material1")),
        ProductType::Product2(String::from("material1"), String::from("material2")),
    ];
    for product_type in array {
        let product = new_product(product_type);
        product.consume()
    }
}
